<?php
/*****************************************************************
 * Fusion.Board
 *
 * @author                Denis Wrobel
 * @license               http://www.gnu.org/licenses/gpl-3.0.html
 * @version               0.1
 *
 *****************************************************************/

if( !defined( 'IN_SCRIPT' ) )
{
    die( 'Go Away!' );
}


class Template
{
    public $root; //Templates Root dir
    public $compile; //Compiled templates dir
    public $template; //Template folder-name
    private $vars = array(); //Template arrays
    public $loops_runs = array(); //Handle loop runs
    public $loops_var = array(); //Handle loop vars
    public $if_states = array();
    public $blocks = array();
    public $loop_if_states = array();
    
    public function checkData()
    {
        global $error;
        if( !isset( $this->root ) )
        {
            $error->scriptError( 'Property `root` from Template class cannot be empty!' );
        }
        elseif( !isset( $this->compile ) )
        {
            $error->scriptError( 'Property `compile` from Template class cannot be empty!' );
        }
        elseif( !isset( $this->template ) )
        {
            $error->scriptError( 'Property `template` from Template class cannot be empty!' );
        }
        elseif( !file_exists( $this->root ) )
        {
            $error->scriptError( 'Templates root directory does not exists, looking for `' . $this->root . '`' );
        }
        elseif( !file_exists( $this->compile ) )
        {
            $error->scriptError( 'Templates compilations directory does not exists, looking for `' . $this->compile . '`' );
        }
        elseif( !file_exists( $this->root . '/' . $this->template ) )
        {
            $error->scriptError( 'Template directory does not exists, looking for `' . $this->template . '` in `' . $this->root . '`' );
        }
        elseif( !file_exists( $this->compile . '/' . $this->template ) )
        {
            $error->scriptError( 'Template compilation directory does not exists, looking for `' . $this->template . '` in `' . $this->compile . '`' );
        }
        
        @require_once( $this->root . '/' . $this->template . '/blocks.php' );
        $this->blocks = $blocks;
    }
    
    public function assignBlock( $block_name, $vars = '' )
    {
        $block = $this->blocks[ $block_name ];
        
        if( is_array( $vars ) )
        {
            foreach( $vars AS $var => $content )
            {
                $block = str_replace( '{' . $var . '}', $content, $block );
            }
        }
        
        return $block;
    }
    
    /*
     * Assign template var
     * @param string $var_name Var name (ID)
     * @param string $var_content Var content
     */
    public function assignVar( $var_name, $var_content )
    {
        if( isset( $var_name ) && isset( $var_content ) )
        {
            //Set new template var
            $this->vars[ $var_name ] = $var_content;
        }
    }
    
    /*
     * Assign multiple vars at one time
     * @param array $vars Vars var => content
     */
    public function assignVars( $vars )
    {
        if( is_array( $vars ) )
        {
            foreach( $vars AS $var => $var_content )
            {
                $this->assignVar( $var, $var_content );
            }
        }
    }
    
    /*
     * Set if as visible
     * @param string $if_name IF Name
     */
    public function setIf( $if_name )
    {
        if( isset( $if_name ) )
        {
            $this->if_states[ $if_name ] = 1;
        }
    }
    
    public function setLoopIf( $ifname, $loop )
    {
        $x = $this->loops_runs[ $loop ]+1;
        $this->loop_if_states[ $loop ][ $ifname ][ $x ] = 1;
    }
    
    private function extractLoopIfs( $data )
    {
        $data = preg_replace( '/<loopif name="(.*?)" loop="(.*?)">/si', '<?php if( $this->loop_if_states[\'$2\'][\'$1\'][ $i ] == 1 ) { ?>', $data );
        $data = preg_replace( '/<endloopif name="(.*?)">/si', '<?php } ?>', $data );
        
        return $data;
    }
    
    /*
     * Set loop
     * @param string $loop_name Loop name
     * @param array $vars Loop vars
     */
    public function setLoop( $loops_name, $vars )
    {
        $this->loops_runs[ $loops_name ]++;
        
        
        if( is_array( $vars ) )
        {
            foreach( $vars AS $var => $content )
            {
                $this->loops_var[ $loops_name ][ $this->loops_runs[ $loops_name ] ][ $var ] = $content;
            }
        }
    }
    
    /*
     * Compile tpl file to php code
     */
    public function compile( $file )
    {
        $directory = $this->root . '/' . $this->template  . '/';
        $compilation = $this->compile . $this->template . '/';
        
        if( file_exists( $directory . $file . '.tpl' ) )
        {
            $content = file_get_contents( $directory . $file . '.tpl' );
            
            $php_content = '<?php' . "\n";
            $php_content .= "\n";
            $php_content .= '$hash = \'' . md5_file( $directory . $file . '.tpl' ) . '\';' . "\n";
            $php_content .= "\n";
            $php_content .= '?>' . "\n";
            
            $compile = $this->extractVars( $content );
            $compile = $this->extractLoops( $compile );
            $compile = $this->extractLoopsVars( $compile );
            $compile = $this->extractNoLoops( $compile );
            $compile = $this->extractIfs( $compile );
            $compile = $this->extractIsLoops( $compile );
            $compile = $this->extractLoopIfs( $compile );
            
            file_put_contents( $compilation . $file . '.php', $php_content . $compile );
        }
    }
    
    
    private function extractVars( $data )
    {
        preg_match_all( '/\{([a-zA-Z0-9_]{0,255})\}/i', $data, $vars );

        
        foreach( $vars[1] AS $var )
        {
            $data = str_replace( '{' . $var . '}', '<?php echo ( isset( $this->vars[\'' . $var . '\'] ) ) ? $this->vars[\'' . $var . '\'] : \'\'; ?>', $data );
        }
        
        return $data;
    }
    
    private function extractLoops( $data )
    {
        $data = preg_replace( '/<loop name="(.*?)">/', '<?php for( $i = 1; $i <= $this->loops_runs[\'$1\']; $i++ ) { $loop_$1 = $this->loops_var[\'$1\'][ $i ]; ?>' , $data );
        $data = preg_replace( '/<endloop name="(.*?)">/', '<?php } ?>' , $data );
        
        return $data;
    }
    
    private function extractNoLoops( $data )
    {
        $data = preg_replace( '/<noloop name="(.*?)">/', '<?php if( !isset( $this->loops_runs[\'$1\'] ) ) { ?>' , $data );
        $data = preg_replace( '/<endnoloop name="(.*?)">/', '<?php } ?>' , $data );
        
        return $data;
    }
    
    private function extractLoopsVars( $data )
    {
        $data = preg_replace( '/\{([a-zA-Z0-9_]{0,255})\.([a-zA-Z0-9_]{0,255})\}/i', '<?php echo ( isset( $loop_$1[\'$2\'] ) ) ? $loop_$1[\'$2\'] : \'\'; ?>', $data );
        
        return $data;
    }
    
    private function extractIfs( $data )
    {
        $data = preg_replace( '/<if name="(.*?)">/si', '<?php if( $this->if_states[\'$1\'] == 1 ) { unset( $this->if_states[\'$1\'] ); ?>', $data );
        $data = preg_replace( '/<endif name="(.*?)">/si', '<?php } ?>', $data );
        
        return $data;
    }
    
    private function extractIsLoops( $data )
    {
        $data = preg_replace( '/<isloop name="([a-zA-Z0-9\._]{0,100})">/si', '<?php if( isset( $this->loops_runs[\'$1\'] ) ) { ?>', $data );
        $data = preg_replace( '/<endisloop name="([a-zA-Z0-9\._]{0,100})">/si', '<?php } ?>', $data );
        
        return $data;
        
        
        return $data;
    }
    
    public function draw( $file )
    {
        if( file_exists( $this->compile . $this->template . '/' . $file . '.php' ) )
        {
            @require_once( $this->compile . $this->template . '/' . $file . '.php' );
            
            if( $hash != md5_file( $this->root . '/' . $this->template  . '/' . $file . '.tpl'  ) )
            {
                $this->compile( $file );
            }
        }
        else
        {
            $this->compile( $file );
            
            @require_once( $this->compile . $this->template . '/' . $file . '.php' );
        }
    }
}

?>